/**
 * Project Reactor
 */


#include "SocketIO.h"

/**
 * SocketIO implementation
 */


/**
 * @param fd
 */
SocketIO::SocketIO(int fd) 
:m_fd(fd)
{

}

SocketIO::~SocketIO() {
    //close(m_fd);
}       

/**
 * @param buf
 * @param len
 * @return int
 */
int SocketIO::readn(char * buf, int len) {
    int left = len;
    char *pstr = buf;
    int ret = 0;
    while(left > 0){
        ret = read(m_fd,pstr,left);
        if(ret == -1 && errno == EINTR){
            continue;
        }else if(-1 == ret){
            perror("read error -1");
            return -1;
        }else if(0 == ret){
            break;
        }else{
            pstr += ret;
            left -= ret;
        }
    }
    return len - left;
}

/**
 * @param buf
 * @param len
 * @return int
 */
int SocketIO::writen(const char * buf, int len) {
    int left = len;
    const char *pstr = buf;
    int ret = 0;
    while(left > 0){
        ret = write(m_fd,pstr,left);
        if(ret == -1 && errno == EINTR){
            continue;
        }else if(-1 == ret){
            perror("writen error -1");
            return -1;
        }else if(0 == ret){
            break;
        }else{
            pstr += ret;
            left -= ret;
        }
    }
    return len - left;
}

/**
 * @param buf
 * @param len
 * @return int
 */
int SocketIO::readline(char * buf, int len) {
    int left = len -1;
    char *pstr = buf;
    int ret = 0,total = 0;
    while(left > 0){
        ret = recv(m_fd,pstr,left,MSG_PEEK);
        //预读取数据，只是复制操作
        if(ret == -1 && errno == EINTR){
            continue;
        }else if(-1 == ret){
            perror("readline error -1");
            return -1;
        }else if(0 == ret){
            break;
        }else{
            for(int idx = 0;idx < ret;++idx){
                if(pstr[idx] == '\n' || pstr[idx] == '\r'){
                    int sz = idx + 1;
                    total += sz;
                    readn(pstr,sz);
                    return total;
                }
            }
            readn(pstr,ret);
            total += ret;
            pstr += ret;
            left -= ret;
        }
    }
    *pstr = '\0';
    return total;
}